from dataclasses import asdict
from typing import Any

from starlette import status
from starlette.requests import Request
from starlette.responses import JSONResponse

from core.utils.json_result import JsonResult, ResultCodeEnum


class CustomerException(Exception):
    """
        自定义异常类
        """

    def __init__(self, message: str):
        self.message = message


class BusinessException(Exception):
    def __init__(self, json_result: JsonResult[Any]):
        self.json_result = json_result


async def customer_exception_handler(request: Request, exc: CustomerException) -> JSONResponse:
    # 这里的content，返回的要是可序列化的，这里使用 asdict转换成dict，不然会报错
    return JSONResponse(status_code=status.HTTP_200_OK,
                        content=asdict(JsonResult(code=ResultCodeEnum.FAIL.value.value,
                                                  message=exc.message,
                                                  data=[{
                                                      "method": request.method,
                                                      "url": str(request.url)  # 注意，这里要将 url转换成str，url默认为URL类型，是不可序列化的
                                                  }])))


async def business_exception_handler(request: Request, exc: BusinessException) -> JSONResponse:
    return JSONResponse(status_code=status.HTTP_200_OK,
                        content=asdict(exc.json_result))


# 全局异常定义
global_exception_handlers = {
    # 当出现 CustomerException时，用 customer_exception_handler 处理
    CustomerException: customer_exception_handler,
    # 当出现 BusinessException，用 business_exception_handler 处理
    BusinessException: business_exception_handler,
}
